
#ifndef SX_COLLISION_EVENT_POOL_H
#define SX_COLLISION_EVENT_POOL_H

#include <sxArrayList.h>

namespace Sx {
namespace Physics {
namespace Collision {
namespace Event {

template <typename EventType>
class CollisionEventPool : public Util::ArrayList<EventType, std::allocator<EventType> > {
public:
	CollisionEventPool();
	CollisionEventPool(unsigned int size);
	virtual ~CollisionEventPool();

	void clear();

	/*
	 * Returns a free index that can be used for a collision event. Collision
	 * events indices are provided in the contiguous memory pool. This function
	 * will always return a valid index into the collision memory pool. If
	 * there is not enough internal room in the pool this function will have to
	 * reallocate internally. This function will incur a performance hit if
	 * this is required to provide a new free collision event index. To avoid
	 * these reallocations, initialize the pool with sufficient space per
	 * the requirements of the use-case.
	 */
	unsigned int getFreeEventIndex();
	unsigned int size() const;

protected:
	unsigned int freeIndex;
};

template <typename EventType>
CollisionEventPool<EventType>::CollisionEventPool() : ArrayList<EventType>(1) {
	this->freeIndex = 0;
}

template <typename EventType>
CollisionEventPool<EventType>::CollisionEventPool(unsigned int size) : ArrayList<EventType>(size, EventType()) {
	this->freeIndex = 0;
}

template <typename EventType>
CollisionEventPool<EventType>::~CollisionEventPool() {

}

template <typename EventType>
void CollisionEventPool<EventType>::clear() {
	this->freeIndex = 0;
}

template <typename EventType>
unsigned int CollisionEventPool<EventType>::getFreeEventIndex() {
	//--------------------------------------------------------------------------
	// Reallocate to provide a valid free index.
	//--------------------------------------------------------------------------
	if ( this->size() == this->capacity() )
		this->imp.resize(static_cast<unsigned int>(std::pow(this->size(), 2.0)));

	unsigned int curFreeIndex = this->freeIndex;
	this->freeIndex++;
	return curFreeIndex;
}

template <typename EventType>
unsigned int CollisionEventPool<EventType>::size() const {
	return this->freeIndex;
}

}

}

}

}

#endif
